// Copyright (C) 2012 by Johann Duscher <jonny.dee@gmx.net>
//
// This file is part of barcodeart-pp.
//
// barcodeart-pp is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// barcodeart-pp is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with barcodeart-pp. If not, see <http://www.gnu.org/licenses/>.

#include <iostream>

#include <QDebug>
#include <QPluginLoader>
#include <QFile>

#include <barcodeart/qrcode/EncoderConfig.hpp>
//#include <barcodeart/qrcode/qrencode/Encoder.hpp>

#include <barcodeart/BorderDecorator.hpp>
#include <barcodeart/SizeDecorator.hpp>

//#include <barcodeart/epswriter/EPSWriter.hpp>
//#include <barcodeart/ansiwriter/ANSIWriter.hpp>
//#include <barcodeart/asciiwriter/ASCIIWriter.hpp>
//#include <barcodeart/pngwriter/PNGWriter.hpp>

#include <barcodeart/qt_plugins.hpp>


using namespace std;
using namespace barcodeart;

int main(int argc, const char *argv[])
{
    // Load libraries dynamically.

    QFile encoderLib("libqrcode_libqrencode.dylib");
    if (!encoderLib.exists())
    {
        qDebug() << "Library " << encoderLib.fileName() << " not found!";
        return -1;
    }

    QPluginLoader encoderLoader(encoderLib.fileName());
    if (!encoderLoader.load())
    {
        qDebug() << "Loading plugin failed!";
        return -1;
    }

    QFile writerLib("libansiwriter.dylib");
//    QFile writerLib("libsvgwriter.dylib");
//    QFile writerLib("libpngwriter.dylib");
//    QFile writerLib("libepswriter.dylib");
//    QFile writerLib("libasciiwriter.dylib");
    if (!writerLib.exists())
    {
        qDebug() << "Library " << writerLib.fileName() << " not found!";
        return -1;
    }

    QPluginLoader writerLoader(writerLib.fileName());
    if (!writerLoader.load())
    {
        qDebug() << "Loading plugin failed!";
        return -1;
    }


    // Create encoder instance and encode content to barcode.

    IEncoderPlugin* pEncoderPlugin = qobject_cast<barcodeart::IEncoderPlugin*>(encoderLoader.instance());
    Q_ASSERT(pEncoderPlugin);

    IEncoderConfig::Ptr pEncoderConfig = pEncoderPlugin->createConfig();
    qrcode::EncoderConfig* pQRCodeEncoderConfig = dynamic_cast<qrcode::EncoderConfig*>(pEncoderConfig.get());
    pQRCodeEncoderConfig->setVersion(4);
    pQRCodeEncoderConfig->setErrorCorrectionLevel(qrcode::ErrorCorrection::HIGH);
    pQRCodeEncoderConfig->setEncodingType(qrcode::Encoding::BINARY);
    pQRCodeEncoderConfig->setCaseSensitive(false);

    IEncoder::Ptr pEncoder = pEncoderPlugin->createEncoder();
    IBarCode::ConstPtr pBarCode = pEncoder->encode(reinterpret_cast<const uint8_t*>(argv[0]), strlen(argv[0]), *pEncoderConfig);


    // Create writer instance and write barcode to stdout.

    IWriterPlugin* pWriterPlugin = qobject_cast<barcodeart::IWriterPlugin*>(writerLoader.instance());
    Q_ASSERT(pWriterPlugin);

    IWriterConfig::Ptr pWriterConfig = pWriterPlugin->createConfig();

    IWriter::Ptr pWriter = pWriterPlugin->createWriter();
    pWriter->write(cout, BorderDecorator(BorderDecorator(*pBarCode, 5), 1, true), *pWriterConfig);
//    pWriter->write(cout, SizeDecorator(BorderDecorator(*pBarCode, 5), 15, 15), *pWriterConfig);

    return 0;
}
